typedef unsigned __attribute__((__mode__(QI))) int8_t;
typedef unsigned __attribute__((__mode__(QI))) uint8_t;
typedef int      __attribute__((__mode__(HI))) int16_t;
typedef unsigned __attribute__((__mode__(HI))) uint16_t;
typedef int      __attribute__((__mode__(SI))) int32_t;
typedef unsigned __attribute__((__mode__(SI))) uint32_t;
typedef int      __attribute__((__mode__(DI))) int64_t;
typedef unsigned __attribute__((__mode__(DI))) uint64_t;

typedef int32_t pid_t;
typedef uint64_t reg_t;
typedef uint64_t ptr_t;
typedef uint64_t uintptr_t;
typedef int64_t intptr_t;
typedef uint64_t size_t;
typedef enum {
    TASK_BLOCKED,
    TASK_RUNNING,
    TASK_READY,
    TASK_EXITED,
} task_status_t;


typedef struct list_node
{
    struct list_node *next, *prev;
} list_node_t;

typedef list_node_t list_head;

typedef struct pcb
{
    /* register context */
    // NOTE: this order must be preserved, which is defined in regs.h!!
    reg_t kernel_sp;
    reg_t user_sp;

    /* previous, next pointer */
    list_node_t list;

    /* process id */
    pid_t pid;

    /* BLOCK | READY | RUNNING */
    task_status_t status;

    /* cursor position */
    int cursor_x;
    int cursor_y;

    /* time(seconds) to wake up sleeping PCB */
    uint64_t wakeup_time;

} pcb_t;
#define NUM_MAX_TASK 16
#define MEM_SIZE 32
#define PAGE_SIZE 4096 // 4K
#define INIT_KERNEL_STACK 0x50500000
#define INIT_USER_STACK 0x52500000
#define FREEMEM_KERNEL (INIT_KERNEL_STACK+PAGE_SIZE)
#define FREEMEM_USER INIT_USER_STACK
pcb_t pcb[NUM_MAX_TASK];
const ptr_t pid0_stack = INIT_KERNEL_STACK + PAGE_SIZE;
pcb_t *__dequeue(list_head *ready_queue){
    list_node_t* head = ready_queue->next;
    ready_queue->next = ready_queue->next->next;
    ready_queue->next->prev = &ready_queue;
    pcb_t *getpcb = (pcb_t *)((void *)head - 0x10);
    return getpcb;
}

void __enqueue(list_head* queue, pcb_t* item)
{
    queue->prev->next = &item->list;
    item->list.prev = queue->prev;
    item->list.next = queue;
    queue->prev = &item->list;
}
list_head ready_queue;
pcb_t * current_running;
int main(){
    ready_queue.next = &ready_queue;
    ready_queue.prev = &ready_queue;
    int i = 0;
    for (i = 0; i < 16; i++){
        pcb[i].list.next = &pcb[i+1].list;
        pcb[i].list.prev = &pcb[i-1].list;
        pcb[i].pid = i;
    }
    for(i=0; i<16; i++){
        __enqueue(&ready_queue, &pcb[i]);
    }
    pcb_t *t1 = __dequeue(&ready_queue);
    pcb_t *t2 = __dequeue(&ready_queue);
    pcb_t *t3= __dequeue(&ready_queue);
}   